#include "ROMS_Menu.h"

//added includes
#include <fstream>
#include <algorithm>	//B.1.b
#include <sstream>
#include <string.h>
using namespace std;
using namespace ROMS;



ROMS_Menu::ROMS_Menu()
{
}

void ROMS_Menu::display_main_menu() const 
{
	//A.3
	cout << "\nMAIN MENU \n";
	cout << "1-Info 2-Read 3-Show 4-Find 5-Update 6-Exit\n";
}
void ROMS_Menu::display_info() const
{
	//A.3
	cout << "\nWard-team Project Part I: Restaurant Order Management System\n";
}
void ROMS_Menu::read_recipes_ingredients(string fname)
{
	//A.1, 2 & 3 merge
	ifstream ist;

	//A.1 read ingredients	//should error check
	int num_rec = get_file_info(ist, "Please enter recipe data file name: ", fname);
	ingredients.clear();	//start with an empty list
	read_file(ist, num_rec, ROMS_Menu::Ingred);
	cout << "read " << ingredients.size() << " ingredient items \n";
	//A.1 read and store the recipe data	//should error check
	ist >> num_rec;
	recipes.clear();	//start with an empty list
	read_file(ist, num_rec, ROMS_Menu::Rec);
	cout << "read " << recipes.size() << " recipes \n";
	ist.close();

	//MGM C
	sort(recipes.begin(), recipes.end());
	sort(ingredients.begin(), ingredients.end());
}
void ROMS_Menu::Read_orders(string fname)
{
	//A.2 read and store the order and order item data 
	ifstream ist;
	int num_orders = get_file_info(ist, "Please enter orders data file name: ", fname);
	orders.clear();	//start with an empty list
	read_file(ist, num_orders, ROMS_Menu::Ord);
	cout << "read " << orders.size() << " orders \n";

	//A.2 read order item data	
	int num_items = 0;
	order_items.clear();	//start with an empty list
	ist >> num_items;
	read_file(ist, num_items, ROMS_Menu::Ord_item);
	cout << "read " << order_items.size() << " order items \n";
	ist.close();

	//MGM C
	sort(orders.begin(), orders.end());
	sort(order_items.begin(), order_items.end());
}
void ROMS_Menu::read_catprds(string fname)
{
	ifstream ist;
	int num_items;
	//A.3 read the category and menu data
	int num_cats = get_file_info(ist, "Please enter file name for category/menu data: ", fname);
	categories.clear();	//start with an empty list
	read_file(ist, num_cats, ROMS_Menu::Cats);
	cout << "read " << categories.size() << " categories \n";

	//A.3 read menu items	//should error check
	ist >> num_items;	//get number of menu items
	menu_items.clear();	//start with an empty list
	read_file(ist, num_items, Menu_entry);
	cout << "read " << menu_items.size() << " menu items \n";
	ist.close();

	//MGM C
	sort(categories.begin(), categories.end());
	sort(menu_items.begin(), menu_items.end());

	return;
}
void ROMS_Menu::show() const 
{	//Below is some old code from Part I. What changes, if any are needed for Part II?
	//B.1, a, b, c merge	//cout << "Show queries \n";
	cout << "Enter Show query number:" << endl << "1-Menu Item Recipe 2-All Menu Items by Chef 3-All Menu Items in a Category\n";
	int query_num;
	cin >> query_num;
	switch (query_num) 
	{
	case 1:
		{
			//B.1.a show a Menu Item Recipe
			string item_name;
			int i;
			cout <<"Enter Menu Item Name\n";
			cin >> item_name;
			for (i = 0; i < (int) menu_items.size(); ++i)
				if (menu_items[i].get_name() == item_name) break;
			if (i == (int) menu_items.size()) {
				cout << "Menu Name Not Found\n";
				break;
			}
			else {//found Menu Item, now find recipe and print it
				cout << menu_items[i].get_description() << endl;
				int rec_id = menu_items[i].get_recipe_id();
				int j;
				for (j = 0; j < (int) recipes.size(); ++j)
					if(rec_id == recipes[j].get_rec_id()) break;
				if (j == (int) recipes.size()) {
					cout << "Recipe ID not found -- data bug\n";
					break;
				}
				//print recipe j
				cout << recipes[j].display() << endl;
				//retrieve and print recipe j ingredients
				for (int k = 0; k < (int) ingredients.size(); ++k)
					if(rec_id == ingredients[k].get_rec_id()) cout << ingredients[k].display() << endl;
				cout << endl;
			}
		}
	case 2: 
		{
			//B.1.b list All Menu Items by Chef
			cout << menu_items.size() << " menu items sorted by chef\n";
			vector<Recipe> temp_recipes = recipes;
			//sort the recipes by chef, then print the menu items in the order of their recipe
			sort(temp_recipes.begin(), temp_recipes.end(), SortRecipesByChef());
			for (int i = 0; i< (int) temp_recipes.size(); ++i) {
				cout << "Chef: " << temp_recipes[i].get_chef() << endl;
				//loop thru sorted recipes and print requested coresponding Menu_Item info
				for (int j = 0; j< (int) menu_items.size(); ++j)
					if (menu_items[j].get_recipe_id() == temp_recipes[i].get_rec_id())
							cout << '\t' << menu_items[i].display() << endl;
			}
			cout << endl;
			break;
		}
	case 3:
		{
			//B.1.c All Menu Items in a Category
			cout << "Not implemented";
			cout << endl;
			break;
		}
	
	default:
		cout << "Invalid request\n";
	}
	
}
void ROMS_Menu::find() const 
{	//Below is some old code from Part I. What changes, if any are needed for Part II?
	//cout << "Find queries \n";
	//B.2.a,b,c merge 
	cout << "Enter find query number:" << endl;
	cout << "1-Total Sales for a Table 2-Total Sales for a Server 3-Total Sales for a Menu Item\n";
	int find_num;
	cin >> find_num;
	switch (find_num) 
	{
	case 1:
		//cout << "Not implemented\n";
		//break;
		{
			//B.2.a calculate total sales for a given table
			//read table id
			//loop thru orders that have that table, pick order items for those orders, calc menu_item price * qty ordered and add to total
			//print total
			int table_id;
			cout << "Enter Table ID: ";
			cin >> table_id;
			//validate category id
			
			double sales_total = 0;
			//total up all sales for this table.
			for (int i = 0; i < (int)orders.size(); ++i)
			{
				//select an order that includes this table
				if(table_id == orders[i].get_table_id())
				{
					//add this order sales to the table sales total
					int order_id = orders[i].get_order_id();
					for (int j = 0; j < (int)order_items.size(); ++j)
						//select an order item for the current order
						if(order_id == order_items[j].get_order_id()) {
							int menu_item_id = order_items[j].get_menu_item_id();
							double item_price = 0.;
							for (int k = 0; k < (int) menu_items.size(); ++k) 
								if(menu_item_id == menu_items[k].get_menu_item_id()) 
								{
									item_price = menu_items[k].get_price();
									break;
								}
							//add the sale of this item to the table total
							sales_total += item_price * order_items[j].get_qty();
						}
				}
			}
			cout << " Table sales = "<< sales_total << endl;
			break;
		}
	case 2: 
		{
		//B.2.b Total Sales for a Server
			
			cout << "Not implemented" << endl;
			break;
		}
	case 3:
		{
			//B.2.c Total Sales for a Menu Item
			cout << "Not Implemented" << endl;
			break;
		}
	default:
		cout << "Invalid request\n";
	}
}
void ROMS_Menu::update()  
{	//This is some old code from Part I. What changes, if any are needed for Part II?
	//B.3.a, b, c merge //cout << "Update queries \n";
	cout << "Enter update query number: " << endl;
	cout << "1-Add New Order Item 2-Add New Menu Item 3-Add New Categories" << endl;
	int query_num;
	cin >> query_num;
	switch (query_num) 
	{
	case 1:
		{
			//B.1 Add new order item to an existing order
			int order_id, menu_item_id, qty;
			string seat_id;
			cout << "Enter Order_id    Menu_item_id    quantity   seat_id\n";
			cin >> order_id >> menu_item_id >> qty >> seat_id;
			if(!cin) throw InvalidData();
			//check that order_id exists
			int n = 0;
			for(n=0; n<(int)orders.size(); ++n)
				if(orders[n].get_order_id() == order_id) break;
			if(!(n < (int)orders.size())||!cin) throw InvalidData();
			//check that menu item id exists
			n = 0;
			for(n=0; n<(int)menu_items.size(); ++n)
				if(menu_items[n].get_menu_item_id() == menu_item_id) break;
			if(!(n < (int)menu_items.size())||!cin) throw InvalidData();
			//check that quantity is positive--maybe should check some reasonable upper bound, too?
			if(qty < 1) 
				throw InvalidData();
			//check that seat is valid
			if(seat_id < "A" || seat_id > "H")
				throw InvalidData();
			
			//add order item
			order_items.push_back(Order_Item(seat_id, order_id, menu_item_id, qty));

			cout << "Number of order items is now " << order_items.size() << endl;
			break;
		}
	case 2: 
		{
			//B.3.b Add new menu item using an existing recipe to an existing category
			cout << "Not Implemented" << endl;
			break;
		}
	case 3:
		{
			//B.3.c Add New Categories Soups, Salads and Sides
			cout << "Not Implemented " << endl;
			break;
		}
	default:
		cout << "Invalid request\n";
	}
}

void ROMS_Menu::SaveExit()
{
	using namespace std;
	ofstream myfile;
	myfile.open ("state.dat");
	
	myfile << "4";		//This index means the following are categories
	for (int i=0; i < categories.size(); ++i) {
		myfile << endl << categories[i].get_cat_id() << "\t" << categories[i].get_cat_name();
		}   

	myfile << endl <<endl << "11";		//This index means the following are menu items
		for (int i=0; i < menu_items.size(); ++i) {
			myfile << endl << menu_items[i].get_name() << "\t" << menu_items[i].get_recipe_id() << "\t" << menu_items[i].get_description() << "\t" << menu_items[i].get_menu_item_id() << "\t" << menu_items[i].get_price();
			} 
	
	myfile << endl <<endl << "101";		//This index means the following are orders
		for (int i=0; i < ingredients.size(); ++i) {
			myfile << endl << ingredients[i].display() << "\t" << ingredients[i].get_rec_id();
			}   
	
	
	myfile << endl <<endl << "218";		//This index means the following are orders
		for (int i=0; i < orders.size(); ++i) {
			myfile << endl << orders[i].get_order_id() << "\t" << orders[i].get_server_id() << "\t" << orders[i].get_table_id() << "\t" << orders[i].get_order_date() << "\t" << orders[i].get_order_time();
			}   

	myfile << endl <<endl << "218";		//This index means the following are orders items
		for (int i=0; i < order_items.size(); ++i) {
			myfile << endl << order_items[i].get_seat_id() << "\t" << order_items[i].get_order_id() << "\t" << order_items[i].get_menu_item_id() << "\t" << order_items[i].get_qty();
			}   
	
	myfile.close(); 
}					
//open a file and return the expected number of records
int ROMS_Menu::get_file_info(ifstream& ist, string ptompt, string fname)
{	
	//A.1, 2 & 3 merge
	//string fname;
	//cout << prompt;
	//cin >> fname;
	ist.clear();
	ist.open(fname.c_str());
	if (!ist) throw InvalidFile();
	int num;
	ist >> num;
	if (!ist) throw InvalidData();
	return num;
}
void ROMS_Menu::read_file(ifstream& file, int num_rec, Rec_type ftype)
{
	//A.1, 2 & 3 merge
	//Category_ID Cat_name 
	//example category data: 1010	Appetizers	
	int cat_id;
	string cat_name;

	//Menu_item_ID Category_ID RecipeID Menu_item_name Menu_item_price Description #
	//example menu_item data:	2173	1010	3000	Pastel	2	fried flour dumpling filled with vegetables and meat #
	int menu_item_id, /*cat_id,*/ rec_id;
	string item_name;
	double item_price;
	string item_dscrp;

	//Order_ID Server_ID Table_ID Order_date Order_time
	//example order data: 7000	6220	1000	2011	4	4	1	11
	int order_id, server_id, table_id;
	int order_year, order_month, order_day;
	int order_hour, order_minute;

	//Seat_ID Order_ID Menu_item_ID Quantity_ordered
	//example order_item data:	A	7000	2834	1
	string seat_id; 
	/*int order_id, menu_item_id;*/ 
	int ord_qty;

	//Ingredient_ID Recipe_ID Amount_required Units Name 
	//example ingredient data: 6000	3619	5	medium	onionssliced
	int ingred_id; /*rec_id*/ 
	float amt_req;
	string units, name;

	//Recipe_ID Chef_name Instructions # 
		//example recipe data:	3015	Astrid	1. Liquidise the prawn meat till smooth. Mix in the tapioca flour, salt and pepper. Mix well into a stiff dough.
//2. Divide dough into three equal portions. Roll up each portion then place the rolls on a greased plate. Steam for 40 to 45 minutes over high flame.
//3.Leave the rolls to cool, then wrap with a clean tea towel. Chill well in the refrigerator. Use a very sharp knife to slice thinly. Thoroughly dry the cut-out pieces in the sun.
//4. Deep-fry the crackers   #	
	//int rec_id;
	string chef_name;
	string instr;

	//read given file
	int i = 0; 
	while(file && i < num_rec)
	{
		switch(ftype) {	//Rec_type{ Cats=1, Menu_entry, Rec, Ingred, Ord, Ord_item };
			case ROMS_Menu::Rec:
				file >> rec_id >> chef_name;
				instr = get_long_string(file);
				recipes.push_back(Recipe(rec_id, chef_name, Instructions(instr)));
				break;
			case ROMS_Menu::Ingred:
				file >> ingred_id >> rec_id >> amt_req >> units >> name;
				ingredients.push_back(Ingredient(ingred_id, rec_id, amt_req, units, name));
				break;
			case ROMS_Menu::Ord:
				file >> order_id >> server_id >> table_id >> order_year >> order_month >> order_day >> order_hour >> order_minute;
				orders.push_back(Order(order_id, server_id, table_id, Date(order_year, (Date::Month)order_month, order_day), Time(order_hour,order_minute)));
				break;
			case ROMS_Menu::Ord_item:
				file >> seat_id >> order_id >> menu_item_id >> ord_qty;
				order_items.push_back(Order_Item(seat_id, order_id, menu_item_id, ord_qty));
				break;
			case ROMS_Menu::Cats:
				file >> cat_id >> cat_name;
				categories.push_back(Category(cat_id, cat_name));
				break;
			case ROMS_Menu::Menu_entry:
				file >> menu_item_id >> cat_id >> rec_id >> item_name >> item_price;
				item_dscrp = get_long_string(file);
				menu_items.push_back(Menu_Item(menu_item_id, cat_id, rec_id, item_name, item_price, Description(item_dscrp)));
				break;
			default:
				throw InvalidData();
		}
		++i;
	}
	if(i != num_rec || !file) throw InvalidData();
}
string ROMS_Menu::get_long_string(ifstream& file) 
{
	string result, s;
	file >> result;
	if(result == "#") return "";
	char chr;
	file >> noskipws >> chr;
	while (file && !(chr == '#')) {
		stringstream ss;
		ss << result << chr;
		result = ss.str();
		file >> noskipws >> chr;
	}
	file >> skipws;
	return result;
}

//show functions added to support GUI interface
//Modified by MGM B2 (because tables_button (order item) and Recipes_button (recipe) were swapped before)
string ROMS_Menu::show_button(Msg_type type)
{
	switch(type) {
	case Tables_button: case Show_orderitems:
		return showOrderItem(order_items, orders, menu_items, "Order Items");
	case Orders_button: case Show_order:
		return showOrder(orders, "Orders");
	case Categories_button: case Show_categories:
		return showCategories(categories, menu_items , "Category");
	case Menu_items_button: case Show_menu:
		return showMenuItem(menu_items, "Menu Items");
	case Recipes_button: case Show_recipe:
		return showRecipe(recipes, "Recipes");
	default:
		throw InvalidType();
}

}

//MGM B2: Start
string ROMS_Menu::showOrder(vector<Order> ord, string s)
{
	stringstream ss;
	string r;
	if(ord.size() == 0)
		r = "No "+s+" Data Loaded\n";
	else
	{
		string* matrixOrder = new string[5 * (ord.size()+1)];
		matrixOrder[0] = "Order ID";
		matrixOrder[1] = "Server ID";
		matrixOrder[2] = "Table ID";
		matrixOrder[3] = "Date";
		matrixOrder[4] = "Time";
		int len0=10, len1=11, len2=10, len3=6, len4=6;
		for(int i = 0; i < ord.size(); i++)
		{
			stringstream ss1, ss2, ss3, ss4, ss5;
			ss1 << ord[i].get_order_id();
			matrixOrder[5+(5*i)] = ss1.str();
			if(matrixOrder[5+(5*i)].length()+2 > len0)
			{
				len0 = matrixOrder[5+(5*i)].length()+2;
			}
			ss2 << ord[i].get_server_id();
			matrixOrder[6+(5*i)] = ss2.str();
			if(matrixOrder[6+(5*i)].length()+2 > len1)
			{
				len1 = matrixOrder[6+(5*i)].length()+2;
			}
			ss3 << ord[i].get_table_id();
			matrixOrder[7+(5*i)] = ss3.str();
			if(matrixOrder[7+(5*i)].length()+2 > len2)
			{
				len2 = matrixOrder[7+(5*i)].length()+2;
			}
			ss4 << ord[i].get_order_date();
			matrixOrder[8+(5*i)] = ss4.str();
			if(matrixOrder[8+(5*i)].length()+2 > len3)
			{
				len3 = matrixOrder[8+(5*i)].length()+2;
			}
			ss5 << ord[i].get_order_time();
			matrixOrder[9+(5*i)] = ss5.str();
			if(matrixOrder[9+(5*i)].length()+2 > len4)
			{
				len4 = matrixOrder[9+(5*i)].length()+2;
			}
		}
		
		ss << "List of orders:\n\n|";
		for(int i = 0; i < len0; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len1; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len2; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len3; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len4; i++)
			ss << "-";
		ss << "|\n";
		for(int i = 0; i < ord.size()+1; i++)
		{
			ss << "| " << matrixOrder[0+(5*i)];
			for(int j = 0; j < len0-matrixOrder[0+(5*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixOrder[1+(5*i)];
			for(int j = 0; j < len1-matrixOrder[1+(5*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixOrder[2+(5*i)];
			for(int j = 0; j < len2-matrixOrder[2+(5*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixOrder[3+(5*i)];
			for(int j = 0; j < len3-matrixOrder[3+(5*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixOrder[4+(5*i)];
			for(int j = 0; j < len4-matrixOrder[4+(5*i)].length()-1; j++)
				ss << " ";
			ss << "|\n";
			if(i == 0 || i == ord.size())
			{
				ss << "|";
				for(int j = 0; j < len0; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len1; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len2; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len3; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len4; j++)
					ss << "-";
				ss << "|\n";
			}
			else
			{
				ss << "|";
				for(int j = 0; j < len0; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len1; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len2; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len3; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len4; j++)
					ss << " ";
				ss << "|\n";
			}
		}
		r = ss.str();
	}
	return r;
}

string ROMS_Menu::showRecipe(vector<Recipe> rec, string s)
{
	stringstream ss;
	string r;
	if(rec.size() == 0)
		r = "No "+s+" Data Loaded\n";
	else
	{
		string* matrixRecipe = new string[3 * (rec.size()+1)];
		matrixRecipe[0] = "Recipe ID";
		matrixRecipe[1] = "Chef Name";
		matrixRecipe[2] = "Instructions";
		int len0=11, len1=11, len2=14;
		vector < vector < string > > ins;
		for(int i = 0; i < rec.size(); i++)
		{
			stringstream ss1, ss2, ss3;
			ss1 << rec[i].get_rec_id();
			matrixRecipe[3+(3*i)] = ss1.str();
			if(matrixRecipe[3+(3*i)].length()+2 > len0)
			{
				len0 = matrixRecipe[3+(3*i)].length()+2;
			}
			ss2 << rec[i].get_chef();
			matrixRecipe[4+(3*i)] = ss2.str();
			if(matrixRecipe[4+(3*i)].length()+2 > len1)
			{
				len1 = matrixRecipe[4+(3*i)].length()+2;
			}
			ss3 << rec[i].get_instruction().display();
			ins.push_back(rec[i].get_instruction().splitEnter());
			matrixRecipe[5+(3*i)] = ss3.str();
			for(int j = 0; j < ins[i].size(); j++)
			{
				if(ins[i][j].length()+2 > len2)
				{
					len2 = ins[i][j].length()+2;
				}
			}
		}
		
		ss << "List of recipes:\n\n|";
		for(int i = 0; i < len0; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len1; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len2; i++)
			ss << "-";
		ss << "|\n";
		for(int i = 0; i < rec.size()+1; i++)
		{
			ss << "| " << matrixRecipe[0+(3*i)];
			for(int j = 0; j < len0-matrixRecipe[0+(3*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixRecipe[1+(3*i)];
			for(int j = 0; j < len1-matrixRecipe[1+(3*i)].length()-1; j++)
				ss << " ";
			if(i == 0)
			{
				ss << "| " << matrixRecipe[2+(3*i)];
				for(int j = 0; j < len2-matrixRecipe[2+(3*i)].length()-1; j++)
					ss << " ";
				ss << "|\n";
			}
			else if (i > 0)
			{
				ss << "| " << ins[i-1][0];
				for (int j = 0; j < len2-ins[i-1][0].length()-1; j++)
					ss << " ";
				ss << "|\n";
				for(int j = 1; j < ins[i-1].size(); j++)
				{
					ss << "|";
					for (int k = 0; k < len0; k++)
						ss << " ";
					ss << "|";
					for (int k = 0; k < len1; k++)
						ss << " ";
					ss << "| " << ins[i-1][j];
					for(int k = 0; k < len2-ins[i-1][j].length()-1; k++)
						ss << " ";
					ss << "|\n";
				}
			}
			
			if(i == 0 || i == rec.size())
			{
				ss << "|";
				for(int j = 0; j < len0; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len1; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len2; j++)
					ss << "-";
				ss << "|\n";
			}
			else
			{
				ss << "|";
				for(int j = 0; j < len0; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len1; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len2; j++)
					ss << " ";
				ss << "|\n";
			}
		}
		r = ss.str();
	}
	return r;
}

string ROMS_Menu::showMenuItem(vector<Menu_Item> menu, string s)
{
	stringstream ss;
	string r;
	if(menu.size() == 0)
		r = "No "+s+" Data Loaded\n";
	else
	{
		string* matrixMenu = new string[4 * (menu.size()+1)];
		matrixMenu[0] = "Menu Name";
		matrixMenu[1] = "Menu ID";
		matrixMenu[2] = "Price";
		matrixMenu[3] = "Description";
		int len0=11, len1=9, len2=7, len3=13;
		for(int i = 0; i < menu.size(); i++)
		{
			stringstream ss1, ss2, ss3, ss4;
			ss1 << menu[i].get_name();
			matrixMenu[4+(4*i)] = ss1.str();
			if(matrixMenu[4+(4*i)].length()+2 > len0)
			{
				len0 = matrixMenu[4+(4*i)].length()+2;
			}
			ss2 << menu[i].get_menu_item_id();
			matrixMenu[5+(4*i)] = ss2.str();
			if(matrixMenu[5+(4*i)].length()+2 > len1)
			{
				len1 = matrixMenu[5+(4*i)].length()+2;
			}
			ss3 << "$" << menu[i].get_price();
			matrixMenu[6+(4*i)] = ss3.str();
			if(matrixMenu[6+(4*i)].length()+2 > len2)
			{
				len2 = matrixMenu[6+(4*i)].length()+2;
			}
			ss4 << menu[i].get_description();
			matrixMenu[7+(4*i)] = ss4.str();
			if(matrixMenu[7+(4*i)].length()+2 > len3)
			{
				len3 = matrixMenu[7+(4*i)].length()+2;
			}
		}
		
		ss << "List of menu items:\n\n|";
		for(int i = 0; i < len0; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len1; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len2; i++)
			ss << "-";
		ss << "|";
		for(int i = 0; i < len3; i++)
			ss << "-";
		ss << "|\n";
		for(int i = 0; i < menu.size()+1; i++)
		{
			ss << "| " << matrixMenu[0+(4*i)];
			for(int j = 0; j < len0-matrixMenu[0+(4*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixMenu[1+(4*i)];
			for(int j = 0; j < len1-matrixMenu[1+(4*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixMenu[2+(4*i)];
			for(int j = 0; j < len2-matrixMenu[2+(4*i)].length()-1; j++)
				ss << " ";
			ss << "| " << matrixMenu[3+(4*i)];
			for(int j = 0; j < len3-matrixMenu[3+(4*i)].length()-1; j++)
				ss << " ";
			ss << "|\n";
			if(i == 0 || i == menu.size())
			{
				ss << "|";
				for(int j = 0; j < len0; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len1; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len2; j++)
					ss << "-";
				ss << "|";
				for(int j = 0; j < len3; j++)
					ss << "-";
				ss << "|\n";
			}
			else
			{
				ss << "|";
				for(int j = 0; j < len0; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len1; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len2; j++)
					ss << " ";
				ss << "|";
				for(int j = 0; j < len3; j++)
					ss << " ";
				ss << "|\n";
			}
		}
		r = ss.str();
	}
	return r;
}
//MGM B2: End
//EMG B.3
string ROMS_Menu::showCategories(vector<Category> cats, vector<Menu_Item> menu, string s)
{
		string r;
		if(0==cats.size())
			r = "No "+s+" Data Loaded\n";
		else
			for(int i=0; i<cats.size(); ++i)
			{
				r+=cats[i].display();//outputs the category name and some nice formatting stuff
				for(int j=0; j<menu.size();j++)
				{
					if(cats[i].get_cat_id()==menu[j].get_cat_id())
					{r+=menu[j].get_name();//this is where the menu items in that category get outputted
					r+="\n";}
				}
				r+="\n";
			}
		return r;
}
string ROMS_Menu::showOrderItem(vector<Order_Item> orditems, vector<Order> ord, vector<Menu_Item> menu, string s)
{//If I want to improve this, I would have it format length after menu item
//so that it looks nicer, using the length of the stream to see how much it needs to be extended
	string r;
	if(0==orditems.size())
		r = "No "+s+" Data Loaded\n";
	else
		for(int i=0; i<ord.size(); ++i)
		{
			ostringstream oss;
			oss <<"Order ID: "<< ord[i].get_order_id()<<endl
			<<"-----------"<<endl;
			for(int j=0; j<orditems.size(); ++j)
			{
				if(ord[i].get_order_id()==orditems[j].get_order_id())
				{
				oss<<"Seat: "<<orditems[j].get_seat_id()<<"   Menu Item: ";
					for (int k=0; k<menu.size(); ++k)//this inputs the menu item name into the oss
					{//
						if(orditems[j].get_menu_item_id()==menu[k].get_menu_item_id())//
						{//
						 oss<<menu[k].get_name()<<endl;
						}//
					}//
				oss<<"   Quantity:"<<orditems[i].get_qty()<<endl;
				
				}
				
			}
			
			r+=oss.str();
			r+="\n";
		}
	return r;
}

//MGM C (Server sales, category sales, update order item) : Start
//find server sales
string ROMS_Menu::serverSales(int serverID, string s)
{
	stringstream ss;
	string r;
	if(orders.size()==0 && menu_items.size()==0 && order_items.size()==0)
		r = "No "+s+" Data Loaded\n";
	else
	{
		vector<int> orderId;
		for(int i = 0; i < orders.size(); i++)
			//checking server ID
			if(orders[i].get_server_id() == serverID)
				orderId.push_back(orders[i].get_order_id());
		if(orderId.size() == 0)
		{
			//Server ID not found
			ss << "There are no server: " << serverID << endl;
		}
		else
		{
			//search the order items
			vector<Order_Item> orderan;
			for(int i = 0; i < orderId.size(); i++)
				for(int j = 0; j < order_items.size(); j++)
					if(orderId[i] == order_items[j].get_order_id())
						orderan.push_back(order_items[j]);
			//search the menu items in order item
			double total = 0;
			for(int i = 0; i < orderan.size(); i++)
			{
				//find index of menu item
				int index = 0;
				while(index < menu_items.size() && orderan[i].get_menu_item_id() != menu_items[index].get_menu_item_id())
					index++;
				if(index < menu_items.size())
				{
					//sum total
					total += (menu_items[index].get_price() * orderan[i].get_qty());
				}
			}
			//print
			ss << "Total sales of server " << serverID << ": $" << total << endl;
		}
		r = ss.str();          
	}
	return r;
}
//find category sales
string ROMS_Menu::categorySales(string category, string s)
{
	stringstream ss;
	string r;
	if(categories.size()==0 && menu_items.size()==0 && order_items.size()==0)
		r = "No "+s+" Data Loaded\n";
	else
	{
		int catIndex = 0;
		//Checking category
		while(catIndex < categories.size() && categories[catIndex].get_cat_name() != category)
			catIndex++;
		if(catIndex < categories.size())
		{
			//category exist
			int catID = categories[catIndex].get_cat_id();
			vector<Menu_Item> tempMenu;
			//checking menu item in category
			for(int i = 0; i < menu_items.size(); i++)
				if(menu_items[i].get_cat_id() == catID)
					tempMenu.push_back(menu_items[i]);
			if(tempMenu.empty())
				//menu item do not exist
				ss << "There is no menu item in category: " << category << endl;
			else
			{
				//menu item exist
				double total = 0;
				for(int i = 0; i < tempMenu.size(); i++)
				{
					int menuID = tempMenu[i].get_menu_item_id();
					vector<Order_Item> tempOrdi;
					//search menu in order item
					for(int j = 0; j < order_items.size(); j++)
						if(order_items[j].get_menu_item_id() == menuID)
							//tempOrdi.push_back(order_items[j]);
							total += (tempMenu[i].get_price() * order_items[j].get_qty());
				}
				//print
				ss << "Total sales of category " << category << ": $" << total << endl;
			}
		}
		else
		{
			//category do not exist
			ss << "There is no category: " << category << endl;
		}
		r = ss.str();
	}
	return r;
}
//update order item (add)
string ROMS_Menu::addOrderItem(string seat, int orderID, string menu, int quantity, string s)
{
	stringstream ss;
	string r;
	if(order_items.empty() && orders.empty() && menu_items.empty())
		r = "No "+s+" Data Loaded\n";
	else
	{
		if(seat == "A" || seat == "B" || seat == "C" || seat == "D" || seat == "E" || seat == "F" || seat == "G" || seat == "H")
		{
			int indexOrder = 0;
			while(indexOrder < orders.size() && orders[indexOrder].get_order_id() != orderID)
				indexOrder++;
			if(indexOrder < orders.size())
			{
				int indexMenu = 0;
				while(indexMenu < menu_items.size() && menu_items[indexMenu].get_name() != menu)
					indexMenu++;
				if(indexMenu < menu_items.size())
				{
					if(quantity <= 0)
						ss << "Your quantity is 0 and you can not order 0 item. Please input a more than 0 quantity.\n";
					else
					{
						order_items.push_back(Order_Item(seat, orderID, menu_items[indexMenu].get_menu_item_id(), quantity));
						sort(order_items.begin(), order_items.end());
						if(quantity == 1)
						{
							ss << "You have succesfully ordered a " << menu << " while sitting on seat " << seat << " in order " << orderID << ".\n";
						}
						else
						{
							ss << "You have succesfully ordered " << quantity << " " << menu << "(s) while sitting on seat " << seat << " in order " << orderID << ".\n";
						}
					}
				}
				else
					ss << "Menu " << menu << " is not found. Please input a correct menu item.\n";
			}
			else
			{
				ss << "Order ID " << orderID << " is not found. Please input a correct Order ID.\n";
			}	
		}
		else
		{
			ss << "There is no seat ID " << seat << ". Please input a correct seat ID (A, B, C, D, E, F, G, or H).\n";
		}
		r = ss.str();
	}
	return r;
}
//update order (add)
string ROMS_Menu::addOrder(int serverID, int tableID, string strDate, string strTime, int pil, string s)
{
	stringstream ss;
	string r;
	if(orders.empty())
		r = "No "+s+" Data Loaded\n";
	else
	{
		if(serverID > 999)
		{
			if(tableID > 999)
			{
				if(pil == 1)
				{
					//Parse and make date
					vector<string> vecDate;
					char* pch;
					pch = strtok((char*)strDate.c_str(), "/");
					while (pch != NULL)
					{
						vecDate.push_back(pch);
						pch = strtok(NULL, "/");
					}
					if(vecDate.size() == 3 && vecDate[0].length() == 4)
					{
						int year = atoi(vecDate[0].c_str());
						Date::Month month = (Date::Month)atoi(vecDate[1].c_str());
						int day = atoi(vecDate[2].c_str());
						if(Chrono::is_date(year, month, day))
						{
							Date date(year, month, day);
							//Parse and make time
							vector<string> vecTime;
							char* dph;
							dph = strtok((char*)strTime.c_str(), ":");
							while (dph != NULL)
							{
								vecTime.push_back(dph);
								dph = strtok(NULL, ":");
							}
							if(vecTime.size() == 2)
							{
								int hour = atoi(vecTime[0].c_str());
								int minute = atoi(vecTime[1].c_str());
								if(hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59)
								{
									Time time(atoi(vecTime[0].c_str()), atoi(vecTime[1].c_str()));
									int orderID = orders[orders.size()-1].get_order_id() + 1;
									orders.push_back(Order(orderID, serverID, tableID, date, time));
									ss << "You have successfully added an order: order " << orderID << ", server " << serverID << ", table " << tableID << ", date " << date << ", time " << time << ".";
								}
								else
									ss << "Time is not valid. Please input a valid time in format \"h:m\".";
							}
							else
								ss << "Time format is not correct. Please input time in format \"h:m\".";
						}
						else
							ss << "Date is not valid. Please input a valid date in format \"yyyy/m/d\".";
					}
					else
						ss << "Date format is not correct. Please input date in format \"yyyy/m/d\".";
				}
				else if(pil == 2)
				{
					time_t t = time(0);
					struct tm * curr_time = localtime( &t );
					Date date ( curr_time->tm_year + 1900, (Date::Month)((curr_time->tm_mon) + 1), curr_time->tm_mday );
					Time time ( curr_time->tm_hour, curr_time->tm_min );
					int orderID = orders[orders.size()-1].get_order_id() + 1;
					Order order ( orderID, serverID, tableID, date, time );
					orders.push_back( order );
					ss << "You have successfully added: order " << orderID << ", server " << serverID << ", table " << tableID << ", date " << date << ", time " << time << ".";
				}
			}
			else
				ss << "Table ID must at least have 4 digits.";
		}
		else
			ss << "Server ID must at least have 4 digits.";
		r = ss.str();
	}
	return r;
}
//update order item (delete)
string ROMS_Menu::delOrderItem(string seat, int orderID, string menu, int quantity, string s)
{
	stringstream ss;
	string r;
	if(order_items.empty() && orders.empty() && menu_items.empty())
		r = "No "+s+" Data Loaded\n";
	else
	{
		int indexOrder = 0;
		while(indexOrder < orders.size() && orders[indexOrder].get_order_id() != orderID)
			indexOrder++;
		if(indexOrder < orders.size())
		{
			int indexMenu = 0;
			while(indexMenu < menu_items.size() && menu_items[indexMenu].get_name() != menu)
				indexMenu++;
			if(indexMenu < menu_items.size())
			{
				int menuID = menu_items[indexMenu].get_menu_item_id();
				int j = 0;
				while(j < order_items.size() && (order_items[j].get_order_id() != orderID || order_items[j].get_seat_id() != seat || order_items[j].get_menu_item_id() != menuID || order_items[j].get_qty() != quantity))
				{
					j++;
				}
				if (j < order_items.size())
				{
					order_items.erase(order_items.begin() + j);
					if(quantity == 1)
						ss << "You have succesfully deleted: a " << menu << " from order ID: " << orderID << ", while sitting on seat " << seat << ".";
					else
						ss << "You have succesfully deleted: " << quantity << " " << menu << "(s) from order ID: " << orderID << ", while sitting on seat " << seat << ".";
				}
				else
				{
					ss << "There is no order item with order ID " << orderID << ", seat " << seat << ", menu item " << menu << ", and quantity " << quantity << ".\n\n";
				}
			}
			else
				ss << "Menu " << menu << " is not found. Please input a correct menu item.\n";
		}
		else
		{
			ss << "Order ID " << orderID << " is not found. Please input a correct Order ID.\n";
		}	
		r = ss.str();
	}
	return r;
}
//MGM C (Server sales, category sales, and add order item) : End
//EMG C
string ROMS_Menu::findMenuItemSales(int menuID, string s)
{
	cout<<"Button Pressed"<<endl;
	//need meni items, orderitems
	//needs to be defined and called in the main
	int item_id_s;
	int menu_index=-1;
	double item_price_s;
	double total=0;
	stringstream ss;
	string output;
	if(order_items.empty() || menu_items.empty())
		output = "No "+s+" Data Loaded\n";
	else
	{
		for (int i=0; i<menu_items.size();i++)
		{
			if(menu_items[i].get_menu_item_id()==menuID)
			menu_index=i;
		}
		if(menu_index==-1)//then the menu item doesn't exist
			ss<<"That menu item id doesn't exist"<<endl;
		else//now find total
		{
			item_id_s=menu_items[menu_index].get_menu_item_id();//turn the number the user picked into the menu item id
			item_price_s=menu_items[menu_index].get_price();//get the price of the item the user picked
			
			for(int i=0; i<order_items.size();i++)//now we move through each item of order_items
				{//if the id of the entry is same, add price*quantity to total
					if(item_id_s==order_items[i].get_menu_item_id())
					{
						total+=(item_price_s*order_items[i].get_qty());
					}
				}
			if (total>0)
				ss<<"total= "<<total<<endl;
			else
				ss<<"That menu item wasn't ever sold."<<endl;
		}
		output=ss.str();
		return output;
	}
}
string ROMS_Menu::addCategory(string catName, string s)
{
	bool exists=false;
	stringstream ss;
	int newId=1000;
	if (categories.empty())
		{
			ss<<"No current entries";
		}
	else
	{
		for(int i=0;i<=categories.size()-1;i++)
		{
			if (newId==categories[i].get_cat_id())
				newId++;
			if (catName==categories[i].get_cat_name())
				exists=true;
		}

		if(exists)
			{
			ss<<"That category already exists";
			}
		else
			{
			categories.push_back(Category(newId,catName));
			ss<<"Category "<<catName<<" added with ID: "<<newId;
			}
	}
	string output=ss.str();
	return output;
}

// find table sales 
// Code from MGM
string ROMS_Menu::tableSales(int tableID, string s)
{
stringstream ss;
string r;

	if(orders.size()==0 && menu_items.size()==0 && order_items.size()==0)
		r = "No "+s+" Data Loaded\n";
	else
	{
	vector<int> orderId;
		for(int i = 0; i < orders.size(); i++)
		//checking server ID
			if(orders[i].get_table_id() == tableID)
			orderId.push_back(orders[i].get_order_id());
		if(orderId.size() == 0)
		{
			//table ID not found
			ss << "There is no table: " << tableID << endl;
		}
	else
	{
	//search the order items
	vector<Order_Item> orderan;
		for(int i = 0; i < orderId.size(); i++)
			for(int j = 0; j < order_items.size(); j++)
				if(orderId[i] == order_items[j].get_order_id())
					orderan.push_back(order_items[j]);
				//search the menu items in order item
				double total = 0;
					for(int i = 0; i < orderan.size(); i++)
					{
						//find index of menu item
						int index = 0;
						while(index < menu_items.size() && orderan[i].get_menu_item_id() != menu_items[index].get_menu_item_id())
							index++;
						if(index < menu_items.size())
						{
							//sum total
							total += (menu_items[index].get_price() * orderan[i].get_qty());
						}
					}
				//print
				ss << "Total sales of table " << tableID << ": $" << total << endl;
			}
		r = ss.str();          
	}
return r;
}
int magic = 0;
string ROMS_Menu::addMenuItem(int MenuID, int Cat, int RecipeID, string Name, double Price, string Desc, string s)
{
	MenuID = 2000+magic;
	stringstream ss;
	string r;
	if(order_items.empty() && orders.empty() && menu_items.empty() )
		r = "No "+s+" Data Loaded\n";
	else
	{
		if(Cat > 999)
	{
			int indexOrder = 0;
			while(indexOrder < orders.size() ) //&& orders[indexOrder].get_order_id() != orderID)
				indexOrder++;
			if(RecipeID > 999)
			{
				int indexMenu = 0;
				while(indexMenu < menu_items.size() ) //&& menu_items[indexMenu].get_name() != menu)
					indexMenu++;
				if(Name.size()!=0)
				{
					if(Price >= 0)
					{				
					
						menu_items.push_back(Menu_Item(MenuID, Cat, RecipeID, Name, Price, Desc));
						sort(order_items.begin(), order_items.end());
						
							ss << "You added " << Name << " of category " << Cat << " using recipe ID " << RecipeID << " with a price of $" << Price << ".\n";
						}
					
				}
				else
					ss << "The name " << Name << " is not found. Please input a correct menu item.\n";
			}
			else
			{
				ss << "Category " << Cat << " is not found. Please input a correct Category ID.\n";
			}	
		}
		
		r = ss.str();
	magic++;
	return r;
	}
}
